#include <cuda.h>
#include <stdio.h>
#include <stdlib.h>

#define N 64

// Device code
__global__ void vecAdd(int* A, int* B, int* C)
{
	int i = threadIdx.x;
	C[i]=A[i]+B[i];
}

// Host code
int main()
{
	//allocate host memory
	int* A= (int*)malloc(N*sizeof(int));
	int* B= (int*)malloc(N*sizeof(int));
	int* C= (int*)malloc(N*sizeof(int));

	//init gpu memory
	int* AGpu;
	int* BGpu;
	int* CGpu;
	cudaMalloc((void**)&AGpu,N*sizeof(int));
	cudaMalloc((void**)&BGpu,N*sizeof(int));
	cudaMalloc((void**)&CGpu,N*sizeof(int));

	//fill A and B
	for(int i=0; i<N;i++){
		A[i]=i;
		B[i]=i;
		C[i]=0;
	}

	//copy A and B to gpu
	cudaMemcpy(AGpu,A,N*sizeof(int),cudaMemcpyHostToDevice);
	cudaMemcpy(BGpu,B,N*sizeof(int),cudaMemcpyHostToDevice);

	//compute C on GPU
	printf("sumUp Arrayvecs: \n\n");
	vecAdd<<<1,N>>>(AGpu,BGpu,CGpu);

	//Copy C from gpu to host memory
	cudaMemcpy(C,CGpu,N*sizeof(int),cudaMemcpyDeviceToHost);

	//output result for verification
	for(int i=0; i<N;i++){
		printf("%d + %d = %d\n",A[i],B[i],C[i]);
	}

	//cleanup host memory
	free(A);
	free(B);
	free(C);
	//cleanup GPU memory
	cudaFree(AGpu);
	cudaFree(BGpu);
	cudaFree(CGpu);

	return 0;
}
